/// Author: QP
/// Version: 0.8
/// Date:2022/07
/// 互联互通文章转FHIR资源工具
Class HCC.Utils.HCC2FHIR Extends %RegisteredObject
{

Parameter Debug = 1;

/// debug mode. If set to true, will save generated SDA into Debug path
Property Debug As %Boolean [ InitialExpression = 0 ];

/// full path to store SDA file in debug mode
Property DebugPath As %String;

/// full path of the xslt file 
Property XSLT As %String [ Internal ];

/// xslt transformer
Property Transformer As HS.Util.XSLTTransformer [ Internal ];

/// batch transformation to FHIR R4
/// Input parameters:
/// 1. pHCCDir: directory of HCC documents 
/// 2. pTargetDir: target directory of generated FHIR
/// 3. pSDADir: directory of generated intermedial SDA documents
ClassMethod BatchTransfer2FHIRFromFile(pHCCDir = "/isc/irishealth/csp/xslt/CDA脱敏", pTargetDir = "/isc/irishealth/csp/xslt/FHIROUT") As %Status
{
	set tST = ##class(%SQL.Statement).%New()
	set tSC = tST.%PrepareClassQuery("%File", "FileSet")
	if $$$ISERR(tSC) {write "%Prepare failed:" do $SYSTEM.Status.DisplayError(tSC) quit}

	set tRS = tST.%Execute(pHCCDir, "*.xml;*.XML")
	if (tRS.%SQLCODE '= 0) {write "%Execute failed:", !, "SQLCODE ", rset.%SQLCODE, ": ", rset.%Message quit}
	
	Set tSplit=$Case($system.Version.GetOS(),"Windows":"\",:"/")
	Set tTransformer=..%New("file:///"_$SYSTEM.Util.InstallDirectory()_"csp/xslt/HCC/HCC2SDA.xsl")
	Set tSDAPath = "/isc/irishealth/csp/xslt/SDAOUT"
    
	while tRS.%Next()
	{
		Set tSourceFile = tRS.%Get("Name"), tFileName = $P(tSourceFile,tSplit,$L(tSourceFile,tSplit))
		w tFileName,!
		Set tSource=##class(%Stream.FileBinary).%New()
		Set tSC=tSource.LinkToFile(tSourceFile)
		// transfer to SDA
		Set tTransformer.Debug=1
		Set tTransformer.DebugPath = tSDAPath_tSplit_tFileName,tFHIR=""
	    Set tSC = tTransformer.TransferHCCDocStream2FHIR(tSource,.tFHIR)
	    Quit:($$$ISERR(tSC))
	    
	    // store FHIR into file
	    Set tTargetFile = pTargetDir_tSplit_$P(tFileName,".")_".json"
	    Set tTarget=##class(%Stream.FileCharacter).%New()
	    Set tSC=tTarget.LinkToFile(tTargetFile)
		Quit:($$$ISERR(tSC))
	    Set tTarget.TranslateTable="UTF8"
    	Do tTarget.Write(tFHIR.Read())
    	Do tFHIR.%Close(),tTarget.%Save(),tTarget.%Close()

	    w !,tSourceFile," transferred to FHIR with result: ",tSC,!
	    Do tSource.%Close()
	}
	Do tRS.%Close(), tTransformer.%Close()
}

/// tranform HCC doc stream to FHIR stream
/// pHCC: 互联互通文档源stream
/// pFHIR: FHIR目标stream
Method TransferHCCDocStream2FHIR(pHCC, ByRef pFHIR) As %Status
{
	// transfter to SDA first
	Set tSC = ..Transformer.Transform(pHCC,..XSLT,.tOutput)
	Quit:($$$ISERR(tSC)) tSC
	
	// store SDA for debug purpose
    if ..Debug=1
    {
	    Set tSDA=##class(%Stream.FileCharacter).%New()
	    Set tSC=tSDA.LinkToFile(..DebugPath)
	    Set tSDA.TranslateTable="UTF8"
	    Do tSDA.Write(tOutput.Read())
	    D tSDA.%Save(),tSDA.%Close()
    }
	
	// transfer SDA to FHIR
    Set tFHIR = ##class(HS.FHIR.DTL.Util.API.Transform.SDA3ToFHIR).TransformStream(tOutput,"HS.SDA3.Container","R4")
    Quit:('$ISOBJECT(tFHIR)) $$$ERROR(-10000,"SDA transfer to FHIR error!")
    Set:('$ISOBJECT(pFHIR)) pFHIR=##class(%Stream.TmpCharacter).%New()
	Do pFHIR.Write(tFHIR.bundle.%ToJSON())
	Do tFHIR.%Close()
	Quit $$$OK
}

/// This callback method is invoked by the <METHOD>%New</METHOD> method to 
/// provide notification that a new instance of an object is being created.
/// 
/// <P>If this method returns an error then the object will not be created.
/// <p>It is passed the arguments provided in the %New call.
/// When customizing this method, override the arguments with whatever variables and types you expect to receive from %New().
/// For example, if you're going to call %New, passing 2 arguments, %OnNew's signature could be:
/// <p>Method %OnNew(dob as %Date = "", name as %Name = "") as %Status
/// If instead of returning a %Status code this returns an oref and this oref is a subclass of the current
/// class then this oref will be the one returned to the caller of %New method.
Method %OnNew(pXSLT) As %Status [ Private, ServerOnly = 1 ]
{
	Set ..XSLT = pXSLT
	Set ..Transformer= ##class(HS.Util.XSLTTransformer).%New()
	Quit $$$OK
}

ClassMethod Test()
{
	Set x=..%New("file:///C:\Users\DEMO\Desktop\HCCReleaseXSL\HCC2SDA.xsl")
	set tStream = ##class(%Stream.TmpCharacter).%New()
	
	Set tSource=##class(%Stream.FileBinary).%New()
	Set tSC=tSource.LinkToFile("C:\Users\DEMO\Desktop\CDA2FHIR\hccsource\EMR-SD-03-林子涵-1-急诊留观病历.xml")

	S tSC = x.TransferHCCDocStream2FHIR(tSource,.tStream)
	w tStream.Read()
}

}
